package main;

import java.math.BigDecimal;

import simuladores.SimulacaoEnumerativa;
import util.Operacao;
import util.Real;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import custos.CalculadorDeCusto;

public class Simulador {
	private Real precoCompra;

	private BigDecimal quantidadeComprada;

	private BigDecimal quantidadeVendida;

	private Real precoInicial;

	private Real precoFinal;

	private BigDecimal desconto;

	private CalculadorDeCusto calculadorDeCusto;

	public String toString() {
		XStream xstream = new XStream(new DomDriver());
		xstream.alias(getClass().getName().substring(
				getClass().getPackage().getName().length() + 1), getClass());
		return xstream.toXML(this);
	}

	public void imprimir() {
		imprimeResumo();
		imprimeCabecalho();
		simula();
	}

	public Real getCustoCompra() {
		return calculadorDeCusto.calcular(quantidadeComprada, precoCompra,
				Operacao.operacaoFinal, desconto);
	}

	public Real getInvestimentoInicial() {
		return precoCompra.multiply(quantidadeComprada).add(getCustoCompra());
	}

	private void simula() {
		SimulacaoEnumerativa menorLucro = null;
		Real incr = new Real("0.01");
		Real precoVenda = precoInicial;
		SimulacaoEnumerativa simulacao = null;
		while (precoVenda.compareTo(precoFinal) <= 0) {
			simulacao = new SimulacaoEnumerativa(precoCompra, precoVenda,
					quantidadeComprada, quantidadeVendida, getCustoCompra(),
					getInvestimentoInicial(), calculadorDeCusto);
			if (menorLucro == null
					&& simulacao.getLucroBruto().compareTo(new Real("0")) >= 0)
				menorLucro = simulacao;
			imprimeCorpo(simulacao);
			precoVenda = precoVenda.add(incr);
		}
		System.out.println("\n<Menor lucro>");
		imprimeCorpo(menorLucro);
		System.out.println("</Menor lucro>");
		if (simulacao != null)
			System.out.println("Preco Real de Compra = "
					+ simulacao.getPrecoCompraReal());

	}

	private void imprimeCorpo(SimulacaoEnumerativa simulacao) {
		System.out.println(simulacao.getPrecoVenda() + ";"
				+ simulacao.getVariacao() + ";" + simulacao.getCustoTotal()
				+ ";" + simulacao.getLucroBruto() + ";"
				+ simulacao.getLucroBrutoPercentual() + ";"
				+ simulacao.getLucroLiquido() + ";"
				+ simulacao.getLucroLiquidoPercentual() + ";"
				+ simulacao.getRetornoFinalBruto() + ";"
				+ simulacao.getRetornoFinalLiquido());
	}

	private void imprimeCabecalho() {
		System.out
				.println("preco;variacao(%),custoTotal;lucroBruto;lucroBruto(%);lucro liquido;lucro liquido(%);retornoFinalBruto;retornoFinalLiquido");
	}

	private void imprimeResumo() {
		System.out.println("Intervalo : " + precoInicial + " a " + precoFinal);
		System.out.println("Preco compra : " + precoCompra);
		System.out.println("Quantidade : " + quantidadeComprada);
		System.out
				.println("Investimento Inicial : " + getInvestimentoInicial());
		System.out.println("Desconto = " + desconto);
	}

	public Simulador(String corretora, Real precoCompra,
			BigDecimal quantidadeComprada, BigDecimal quantidadeVendida,
			Real precoInicial, Real precoFinal, BigDecimal desconto) {
		this.calculadorDeCusto = new CalculadorDeCusto(corretora, desconto);
		this.precoCompra = precoCompra;
		this.quantidadeComprada = quantidadeComprada;
		this.quantidadeVendida = quantidadeVendida;
		this.precoInicial = precoInicial;
		this.precoFinal = precoFinal;
		this.desconto = desconto;
	}
}